const Queue = require('./queue')
const url = require('url')
const http = require('http');
module.exports = express;
function send(data) {
  if (typeof data === 'string') {
    this.end(data);
    return;
  }
  data = JSON.stringify(data)
  this.end(data)
}
const _queue = Symbol('_queue')
class Express {
  createServer() {
    const server = http.createServer(this.run.bind(this))
    return server;
  }
  listen(port, fn) {
    this.createServer().listen(port, fn);
  }
  [_queue] = new Queue()
  use(url, middleware) {
    if (typeof url === 'function') {
      middleware = url;
      url = '*'
    }
    this[_queue].enqueue({
      method: '*',
      url,
      middleware
    });
  }
  get(url, middleware) {
    this[_queue].enqueue({
      method: 'GET',
      url,
      middleware
    });
  }
  post(url, middleware) {
    this[_queue].enqueue({
      method: 'POST',
      url,
      middleware
    });
  }
  // 判断每个元素是否符合执行条件
  canRun(element, url, method) {
    if (element.method === '*' && element.url === '*') {
      return true;
    } else if (element.method === '*' && element.url === url) {
      return true;
    } else if (element.method === method && element.url === url) {
      return true;
    } else {
      return false;
    }
  }

  // 取出对头元素，判读对头元素是否可以执行
  isFrontRun(front, req, res, next) {
    const { method, pathname } = req;
    let f = this[_queue].front();
    if (f === front) {
      return;
    }
    if (this.canRun(f, pathname, method)) {
      f.middleware(req, res, next);
    } else {
      this[_queue].enqueue(this[_queue].dequeue());
      this.isFrontRun(front, req, res, next);
    }
  }
  run(req, res) {
    // 解析req里边的pathname和query
    let { pathname, query } = url.parse(req.url);
    req.pathname = pathname;
    req.query = query;

    // 给req和res扩展方法
    this.extend(req, res);
    const that = this;
    function next() {
      // 如果对头的任务执行完成后，也出队，并入队
      that[_queue].enqueue(that[_queue].dequeue());
      that.isFrontRun(front, req, res, next);
    }
    const front = this[_queue].front(); // 记录最开始的对头元素
    if (this.canRun(front, req.pathname, req.method)) {
      front.middleware(req, res, next);
    } else {
      this[_queue].enqueue(this[_queue].dequeue());
      this.isFrontRun(front, req, res, next);
    }
  }
  extend(req, res) {
    res.send = send.bind(res)
  }
}

function express() {
  return new Express();
}
